package com.bamboo.tool.factory;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.bamboo.tool.config.BambooToolComponent;
import com.bamboo.tool.config.model.ProjectInfo;
import com.bamboo.tool.config.model.PsiClassCache;
import com.bamboo.tool.config.model.RestfulCloudConfig;
import com.bamboo.tool.constant.StringConstant;
import com.bamboo.tool.entity.*;
import com.bamboo.tool.enums.*;
import com.bamboo.tool.store.Impl.SqliteStoreServiceImpl;
import com.bamboo.tool.store.StoreService;
import com.bamboo.tool.util.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Create by GuoQing
 * Date 2022/1/21 14:25
 *
 * @author guoqing
 * Description
 */
public class FrameworkExecute {

    /**
     * 构建当前项目 api集合
     */
    public static void buildApiMethod(Project project) {


        StoreService storeService = BambooToolComponent.getStoreService();
        RestfulCloudConfig config = project.getService(BambooToolComponent.class).getState();
        ProjectInfo projectInfo = storeService.queryProject(project.getBasePath(), project.getName());
        Map<String, PersistenceInfo> persistenceInfoMap = storeService.getCurrentProjectAllPersistenceInfo(projectInfo.getId().toString());
        if (projectInfo != null && projectInfo.getId() != null) {
            config.setCurrentProject(projectInfo);
            config.getSelectProjects().add(projectInfo.getId());
            SqliteStoreServiceImpl.deleteCurrentProjectInfo(projectInfo.getId().toString());
        }
        List<String> dataTypes = Arrays.stream(DataType.values()).map(DataType::getCode).collect(Collectors.toList());
        Map<String, DataType> dataTypeMap = Arrays.stream(DataType.values()).collect(Collectors.toMap(DataType::getCode, e -> e));
        // 获取所有注解信息
        List<AnnotationInfoSetting> annotationInfoSettings = storeService.getAllAnnotation();
        // 需要扫描的注解分组
        Map<String, Map<String, AnnotationInfoSetting>> scannMap = annotationInfoSettings.stream().filter(e -> e.getEffect().contains("scann")).collect(Collectors.groupingBy(e -> e.getScope(), Collectors.toMap(e -> e.getAnnotationPath(), e -> e)));
        //需要获取属性的注解分组
        Map<String, Map<String, AnnotationInfoSetting>> attributeMap = annotationInfoSettings.stream().filter(e -> e.getEffect().contains("attribute")).collect(Collectors.groupingBy(e -> e.getScope(), Collectors.toMap(e -> e.getAnnotationPath(), e -> e)));
        //字典表配置分组
        Map<String, DataType> dictMap = storeService.getAllDictByCode(dataTypes).stream().collect(Collectors.toMap(BambooDict::getValue, e -> dataTypeMap.get(e.getKey())));

        // java 类型检查器
        JavaClassValidate classValidate = new JavaClassValidate(dictMap);


        List<PsiClassCache> caches = PsiUtils.getALLPsiClass(project, annotationInfoSettings);
        caches.forEach(cache -> {
            AnnotationInfoSetting info = cache.getSetting();

            for (PsiAnnotation e : cache.getAnnotations()) {
                PsiClass psiClass = (PsiClass) e.getParent().getParent();

                ApiClass apiClass = getBambooClass(info, psiClass);
                if (apiClass == null) {
                    continue;
                }
                PersistenceInfo persistenceInfo = persistenceInfoMap.get(apiClass.getClassPath());
                if (persistenceInfo != null && persistenceInfo.getClassPersistenceInfo() != null) {
                    apiClass.setPersistence(persistenceInfo.getClassPersistenceInfo());
                }

                PsiMethod[] methods = psiClass.getMethods();

                //类中不存在方法则跳过
                if (methods.length < 1) {
                    continue;
                }
                // 类注释处理
                classJavaDocBuild(psiClass, apiClass);

                // 类注解处理
                classAnnotationBuild(attributeMap, psiClass, apiClass);

                // 构建所有方法
                List<ApiMethod> apiMethods = new ArrayList<>();
                for (PsiMethod method1 : methods) {
                    PsiMethod method = null;
                    if (method1.isConstructor() || method1.hasModifierProperty("static") || method1.hasModifierProperty("private") || (method1.getContainingClass() != null && method1.getContainingClass().getQualifiedName().equals("java.lang.Object"))) {
                        // 如果方法是static或final则跳过
                        continue;
                    }

                    ApiMethod apiMethod = new ApiMethod();
                    int accessLevel = PsiUtil.getAccessLevel(method1.getModifierList());
                    Map<String, AnnotationInfo> methodAnnotationInfoMap = builAnnotationInfo(method1.getAnnotations());
                    // 判断方法是否在扫描范围内
                    long count = methodAnnotationInfoMap.values().stream().map(f -> f.getAnnotationName()).filter(f -> getAnnotationInfoByCode(scannMap, AnnotationScope.METHOD.getCode(), f) != null).count();
                    if (count < 1) {
                        List<String> strings = info.getOtherParams().get(AttributeEnums.METHOD_SCAN.getCode());
                        if (CollUtil.isNotEmpty(strings)) {
                            String s = strings.get(0);
                            if (!("public".equals(s) && PsiUtil.ACCESS_LEVEL_PUBLIC == accessLevel)) {
                                continue;
                            } else {
                                PsiMethod[] superMethods = method1.findSuperMethods();
                                if (superMethods.length > 0) {
                                    method = superMethods[0];
                                    Map<String, AnnotationInfo> stringAnnotationInfoMap = builAnnotationInfo(superMethods[0].getAnnotations());
                                    methodAnnotationInfoMap.putAll(stringAnnotationInfoMap);
                                    apiMethod.setMethodUrl(StringUtil.urlParse(method.getName()));
                                } else {
                                    method = method1;
                                    apiMethod.setMethodUrl(StringUtil.urlParse(method1.getName()));
                                }

                            }
                        } else {
                            continue;
                        }
                    } else {
                        method = method1;
                    }
                    apiMethod.setMethodName(method.getName());
                    MethodOtherInfo otherInfo = apiMethod.getOtherInfo();


                    for (AnnotationInfo methodAnnotationInfo : methodAnnotationInfoMap.values()) {
                        AnnotationInfoSetting annotationInfoSetting = getAnnotationInfoByCode(attributeMap, AnnotationScope.METHOD.getCode(), methodAnnotationInfo.getAnnotationName());
                        // 如果未配置该注解，则跳过不获取注解属性
                        if (Objects.isNull(annotationInfoSetting)) {
                            continue;
                        }

                        String frameworkCode = annotationInfoSetting.getFramework().getName();
                        Map<String, List<String>> annotationAttributs = methodAnnotationInfo.getAnnotationAttributs();
                        Map<String, List<String>> otherParams = annotationInfoSetting.getOtherParams();
                        Map<String, AnnotationParam> paramMap = annotationInfoSetting.getParams().stream().collect(Collectors.toMap(a -> a.getName(), a -> a));
                        annotationAttributs.forEach((key, value) -> {
                            AnnotationParam annotationParam = paramMap.get(key);
                            if (!Objects.isNull(annotationParam) && CollUtil.isNotEmpty(value)) {
                                methodAnnotation(apiMethod, annotationParam.getType(), value, frameworkCode);
                            }
                        });
                        otherParams.forEach((key, value) -> {
                            methodAnnotation(apiMethod, key, value, frameworkCode);
                        });

                    }

                    methodUrlBuild(apiClass, apiMethod);
                    Map<String, String> paramTagMap = new HashMap<>();
                    // 构建java注释对象
                    JavaDocComment methodDocComment = JavaDocComment.buildJavaDocComment(method.getDocComment());
                    if (!Objects.isNull(methodDocComment)) {
                        String deprecatedDocTag = methodDocComment.getOneJavaDocTag(MethodDocTags.DEPRECATED.getCode());
                        String oneJavaDocTag = methodDocComment.getOneJavaDocTag(MethodDocTags.IGNORE.getCode());
                        String authorTag = methodDocComment.getOneJavaDocTag(MethodDocTags.AUTHOR.getCode());
                        String apiNoteTag = methodDocComment.getOneJavaDocTag(MethodDocTags.API_NOTE.getCode());
                        String versionTag = methodDocComment.getOneJavaDocTag(MethodDocTags.VERSION.getCode());
                        List<JavaDocTag> paramTags = methodDocComment.getJavaDocTags(MethodDocTags.PARAM.getCode());
                        //是否弃用
                        if (CharSequenceUtil.isNotEmpty(deprecatedDocTag)) {
                            otherInfo.setDeprecated(true);
                        }
                        // 是否忽略
                        if (CharSequenceUtil.isNotEmpty(oneJavaDocTag)) {
                            otherInfo.setIgnore(true);
                        }
                        //作者
                        if (CharSequenceUtil.isNotEmpty(authorTag)) {
                            otherInfo.setAuthor(authorTag);
                        }
                        if (CharSequenceUtil.isNotEmpty(apiNoteTag)) {
                            apiMethod.getDesc().put(DescType.API_NOTE.getCode(), apiNoteTag);
                        }
                        if (CharSequenceUtil.isNotEmpty(methodDocComment.getDescription())) {
                            apiMethod.getDesc().put(DescType.JAVA_DOC.getCode(), methodDocComment.getDescription());
                        }
                        if (CharSequenceUtil.isNotEmpty(versionTag)) {
                            otherInfo.setVersion(versionTag);
                        }

                        if (CollUtil.isNotEmpty(paramTags)) {
                            paramTagMap = paramTags.stream().filter(s -> StrUtil.isNotBlank(s.getValue())).filter(s -> StrUtil.isNotBlank(s.getParamName())).collect(Collectors.toMap(JavaDocTag::getParamName, JavaDocTag::getValue, (key1, key2) -> key2));

                        }

                    }
                    Map<String, PsiType> substitutorTypeMap = new HashMap<>(4);
                    PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
                    PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes();
                    if (implementsListTypes.length > 0) {
                        for (int w = 0; w < implementsListTypes.length; w++) {
                            PsiSubstitutor supersubstitutor = implementsListTypes[w].resolveGenerics().getSubstitutor();
                            supersubstitutor.getSubstitutionMap().forEach((k, v) -> {
                                String genericName = k.getName();
                                if (genericName != null && v != null) {
                                    substitutorTypeMap.put(genericName, v.getDeepComponentType());
                                }
                            });
                        }
                    }
                    if (extendsListTypes.length > 0) {
                        for (int w = 0; w < extendsListTypes.length; w++) {
                            PsiSubstitutor supersubstitutor = extendsListTypes[w].resolveGenerics().getSubstitutor();
                            supersubstitutor.getSubstitutionMap().forEach((k, v) -> {
                                String genericName = k.getName();
                                if (genericName != null && v != null) {
                                    substitutorTypeMap.put(genericName, v.getDeepComponentType());
                                }
                            });
                        }
                    }
                    List<JavaFieldInfo> javaFieldInfos = new ArrayList<>();
                    PsiParameterList psiParameterList = method.getParameterList();
                    List<String> methodParams = new ArrayList<>();
                    for (int i = 0; i < psiParameterList.getParametersCount(); i++) {
                        PsiParameter parameter = psiParameterList.getParameters()[i];
                        if (parameter == null) {
                            continue;
                        }
                        PsiType psiType = parameter.getType();
                        String canonicalText = psiType.getCanonicalText();
                        methodParams.add(canonicalText);
                        //是否为需要忽略的参数
                        boolean contains = classValidate.isIgnored(canonicalText);
                        if (contains) {
                            continue;
                        }


                        JavaFieldInfo javaDataType = PsiUtils.buildJavaDataType(psiType, parameter.getName(), substitutorTypeMap, 0, attributeMap, classValidate);


                        classValidate.getSpecifyType(psiType.getCanonicalText());
                        //是否为需要忽略的参数
                        boolean file = classValidate.isFile(psiType.getCanonicalText());
                        if (file) {
                            javaDataType.setRequired(true);
                            otherInfo.setContentType(ContentType.FORM_DATA.getCode());
                        }
                        String paramTag = paramTagMap.get(parameter.getName());
                        if (StrUtil.isNotEmpty(paramTag)) {
                            if (paramTag.contains("|")) {
                                List<String> params = StrUtil.split(paramTag, "|");
                                javaDataType.getDesc().put(DescType.JAVA_TAG_PARAM_DOC.getCode(), params.get(0));
                                List<String> defulValue = new ArrayList<>();
                                for (int j = 1; j < params.size(); j++) {
                                    defulValue.add(params.get(j));
                                }
                                javaDataType.setExampleValue(CollUtil.join(defulValue, ","));
                            } else {
                                javaDataType.getDesc().put(DescType.JAVA_TAG_PARAM_DOC.getCode(), paramTag);
                            }


                        }
                        PsiAnnotation[] annotations = parameter.getAnnotations();
                        if (annotations.length > 0) {
                            Map<String, AnnotationInfo> parameterMap = FrameworkExecute.builAnnotationInfo(annotations);
                            for (AnnotationInfo annotationInfo : parameterMap.values()) {
                                AnnotationInfoSetting setting = getAnnotationInfoByCode(attributeMap, AnnotationScope.MethodParameter.getCode(), annotationInfo.getAnnotationName());
                                // 如果未配置该注解，则跳过不获取注解属性
                                if (Objects.isNull(setting)) {
                                    continue;
                                }
                                Map<String, List<String>> annotationAttributes = annotationInfo.getAnnotationAttributs();
                                Map<String, List<String>> otherParams = setting.getOtherParams();
                                List<AnnotationParam> params = setting.getParams();

                                params.stream().forEach(param -> {
                                    List<String> strings = annotationAttributes.get(param.getName());
                                    if (CollUtil.isEmpty(strings)) {
                                        strings = param.getDefaultValues();
                                    }
                                    if (CollUtil.isNotEmpty(strings)) {
                                        OtherParameterUtil.methodParameter(param.getType(), strings, javaDataType, apiMethod, param);
                                    }

                                });
                                otherParams.forEach((key, value) -> {
                                    if (CollUtil.isNotEmpty(value)) {
                                        OtherParameterUtil.methodParameter(key, value, javaDataType, apiMethod, null);
                                    }
                                });
                            }
                        }
                        if (!javaDataType.getIsIgnore()) {
                            javaFieldInfos.add(javaDataType);
                        }
                    }
                    apiMethod.setMethodParams(methodParams.toString());
                    javaFieldInfos.stream().forEach(javaDataType -> {
                        if (javaDataType.isHeadParam()) {
                            otherInfo.getHeadParams().add(javaDataType);
                        } else if (javaDataType.isPathParam()) {
                            otherInfo.getPathParams().add(javaDataType);
                        } else if (otherInfo.getContentType().equals(ContentType.FORM_DATA.getCode())) {
                            otherInfo.getBodyParams().add(javaDataType);
                        } else if (javaDataType.isQueryParam()) {
                            otherInfo.getQueryParams().add(javaDataType);
                        } else if (otherInfo.getContentType().equals(ContentType.JSON_DATA.getCode())) {
                            List<JavaFieldInfo> children = javaDataType.getChildren();
                            if (CollUtil.isNotEmpty(children)) {
                                children.stream().forEach(s -> otherInfo.getBodyParams().add(s));
                            } else {
                                otherInfo.getBodyParams().add(javaDataType);
                            }

                        } else {
                            List<JavaFieldInfo> children = javaDataType.getChildren();
                            if (CollUtil.isEmpty(children)) {
                                otherInfo.getQueryParams().add(javaDataType);
                            } else {
                                otherInfo.getQueryParams().addAll(children);
                            }
                        }

                    });

                    JavaFieldInfo javaFieldInfo = PsiUtils.buildJavaDataType(method.getReturnType(), "return_type", new HashMap<>(), 0, attributeMap, classValidate);
                    otherInfo.setResponseParam(javaFieldInfo);
                    // 未指定任何requestType 则为All
                    if (CollUtil.isEmpty(apiMethod.getRequestMethods())) {
                        apiMethod.getRequestMethods().add(RequestMethod.ALL.getCode());
                    }


                    if (persistenceInfo != null) {
                        Map<String, MethodPersistenceInfo> stringMethodPersistenceInfoMap = persistenceInfo.getMethodPersistenceInfoMap().get(apiMethod.getMethodName());
                        if (stringMethodPersistenceInfoMap != null) {
                            MethodPersistenceInfo methodPersistence = stringMethodPersistenceInfoMap.getOrDefault(apiMethod.getMethodParams(), new MethodPersistenceInfo());
                            apiMethod.setPersistence(methodPersistence == null ? new MethodPersistenceInfo() : methodPersistence);
                        }

                    }
                    apiMethods.add(apiMethod);
                }
                //类中不存在方法则跳过
                if (CollUtil.isEmpty(apiMethods)) {
                    continue;
                }
                apiClass.getMethods().addAll(apiMethods);

                storeService.saveData(apiClass, projectInfo.getId());
                apiClass = null;
            }
        });
    }

    private static void methodAnnotation(ApiMethod apiMethod, String type, List<String> strings, String frameworkCode) {
        MethodOtherInfo otherInfo = apiMethod.getOtherInfo();
        Map<String, String> heads = otherInfo.getHeads();
        if (AttributeEnums.METHOD_URL.getCode().equals(type)) {
            String methodUrl = strings.get(0);
            if (CharSequenceUtil.isNotEmpty(methodUrl) && !"/".equals(methodUrl)) {
                apiMethod.setMethodUrl(StringUtil.urlParse(methodUrl));
            }
        } else if (AttributeEnums.REQUEST_METHOD.getCode().equals(type)) {
            apiMethod.getRequestMethods().addAll(strings);
        } else if (AttributeEnums.CONTENT_TYPE.getCode().equals(type)) {
            otherInfo.setContentType(strings.get(0));
        } else if (AttributeEnums.HEADERS.getCode().equals(type)) {
            strings.stream().forEach(e -> {
                if (StrUtil.isNotBlank(e) && e.contains("=")) {
                    List<String> split = StrUtil.split(e, "=");
                    if (split.size() > 1) {
                        heads.put(split.get(0).trim(), split.get(0).trim());
                    }

                }
            });

        } else if (AttributeEnums.DESCRIPTION.getCode().equals(type)) {
            apiMethod.getDesc().put(frameworkCode, StrUtil.removeAll(strings.get(0), "'"));
        } else if (AttributeEnums.DEPRECATED.getCode().equals(type)) {
            String value = strings.get(0);
            if (value.equals(StringConstant.TRUE)) {
                otherInfo.setDeprecated(true);
            }

        } else if (AttributeEnums.METHOD_NAME_URL.getCode().equals(type)) {
            apiMethod.setMethodUrl(StringUtil.urlParse(apiMethod.getMethodName()));
        }

    }

    private static void methodUrlBuild(ApiClass apiClass, ApiMethod apiMethod) {
        String classUrl = apiClass.getClassUrl();
        if (CharSequenceUtil.isNotEmpty(classUrl)) {
            apiMethod.setMethodUrl(classUrl + apiMethod.getMethodUrl());
        }
        String poolUrl = apiClass.getPoolUrl();
        if (CharSequenceUtil.isNotEmpty(poolUrl)) {
            apiMethod.setMethodUrl(poolUrl + apiMethod.getMethodUrl());
        }
        if (CharSequenceUtil.isEmpty(apiMethod.getMethodUrl())) {
            apiMethod.setMethodUrl("/");
        }
    }

    @NotNull
    private static ApiClass getBambooClass(AnnotationInfoSetting info, PsiClass psiClass) {
        Module module = ModuleUtilCore.findModuleForPsiElement(psiClass);
        //模块不存在则跳过
        if (module == null) {
            return null;
        }
        ApiClass apiClass = new ApiClass();
        apiClass.setClassName(psiClass.getName());
        apiClass.setClassPath(Objects.requireNonNull(PsiUtilCore.getVirtualFile(psiClass)).getPath());
        apiClass.setModuleName(module.getName());
        apiClass.setSetting(info);
        return apiClass;
    }

    /**
     * 类注解处理
     */
    private static void classAnnotationBuild(Map<String, Map<String, AnnotationInfoSetting>> attributeMap, PsiClass psiClass, ApiClass apiClass) {
        // 获取类注解信息
        Map<String, AnnotationInfo> annotationInfoMap = builAnnotationInfo(psiClass.getAnnotations());

        for (AnnotationInfo annotationInfo : annotationInfoMap.values()) {
            AnnotationInfoSetting setting = getAnnotationInfoByCode(attributeMap, AnnotationScope.CLASS.getCode(), annotationInfo.getAnnotationName());
            // 如果注解未配置则跳过
            if (Objects.isNull(setting)) {
                continue;
            }

            Map<String, List<String>> annotationAttributs = annotationInfo.getAnnotationAttributs();
            List<AnnotationParam> params = setting.getParams();
            for (AnnotationParam param : params) {
                List<String> strings = annotationAttributs.get(param.getName());
                if (CollUtil.isEmpty(strings)) {
                    continue;
                }
                if (AttributeEnums.POOL_URL.getCode().equals(param.getType())) {
                    String poolUrl = strings.get(0);
                    if (CharSequenceUtil.isEmpty(poolUrl) || "/".equals(poolUrl)) {
                        continue;
                    }
                    apiClass.setPoolUrl(StringUtil.urlParse(poolUrl));
                }
                if (AttributeEnums.CLASS_URL.getCode().equals(param.getType())) {
                    String classUrl = strings.get(0);
                    if (CharSequenceUtil.isEmpty(classUrl) || "/".equals(classUrl)) {
                        continue;
                    }

                    if (ParsingTypeEnums.LOWER_FIRST.getCode().equals(param.getParsingType())) {
                        apiClass.setClassUrl(StringUtil.urlParse(StrUtil.lowerFirst(classUrl)));
                    } else if (ParsingTypeEnums.COMMA_DIVISION_LAST_LOWER_FIRST.getCode().equals(param.getParsingType())) {
                        if (classUrl.contains(".")) {
                            List<String> split = StrUtil.split(classUrl, ".");
                            apiClass.setClassUrl(StringUtil.urlParse(StrUtil.lowerFirst(split.get(split.size() - 1))));
                        } else {
                            apiClass.setClassUrl(StringUtil.urlParse(StrUtil.lowerFirst(classUrl)));
                        }
                    } else {
                        apiClass.setClassUrl(StringUtil.urlParse(classUrl));
                    }

                }
            }


            Map<String, List<String>> otherParams = setting.getOtherParams();


            otherParams.forEach((key, value) -> {
                if (AttributeEnums.CLASS_URL_PREFIX.getCode().equals(key)) {
                    apiClass.setClassUrl(value.get(0) + apiClass.getClassUrl());
                }
            });
        }
    }

    /**
     * 类注释处理
     *
     * @param psiClass 类原始对象
     * @param apiClass 类信息
     */
    private static void classJavaDocBuild(PsiClass psiClass, ApiClass apiClass) {
        ClassOtherInfo classOtherInfo = apiClass.getClassOtherInfo();
        JavaDocComment javaDocComment = JavaDocComment.buildJavaDocComment(psiClass.getDocComment());
        if (!Objects.isNull(javaDocComment)) {
            String deprecatedDocTag = javaDocComment.getOneJavaDocTag(ClassDocTags.DEPRECATED.getCode());
            String oneJavaDocTag = javaDocComment.getOneJavaDocTag(ClassDocTags.IGNORE.getCode());
            String authorTag = javaDocComment.getOneJavaDocTag(ClassDocTags.AUTHOR.getCode());
            String apiNoteTag = javaDocComment.getOneJavaDocTag(ClassDocTags.API_NOTE.getCode());
            String versionTag = javaDocComment.getOneJavaDocTag(ClassDocTags.VERSION.getCode());
            //是否弃用
            if (CharSequenceUtil.isNotEmpty(deprecatedDocTag)) {
                classOtherInfo.setDeprecated(true);
            }
            // 是否忽略
            if (CharSequenceUtil.isNotEmpty(oneJavaDocTag)) {
                classOtherInfo.setIgnore(true);
            }
            //作者
            if (CharSequenceUtil.isNotEmpty(authorTag)) {
                classOtherInfo.setAuthor(authorTag);
            }
            if (CharSequenceUtil.isNotEmpty(apiNoteTag)) {
                apiClass.getDesc().put(DescType.API_NOTE.getCode(), apiNoteTag);
            }
            if (CharSequenceUtil.isNotEmpty(javaDocComment.getDescription())) {
                apiClass.getDesc().put(DescType.JAVA_DOC.getCode(), javaDocComment.getDescription());
            }
            if (CharSequenceUtil.isNotEmpty(versionTag)) {
                classOtherInfo.setVersion(versionTag);
            }
        }
    }

    public static AnnotationInfoSetting getAnnotationInfoByCode(Map<String, Map<String, AnnotationInfoSetting>> attributeMap, String code, String annotationPath) {
        Map<String, AnnotationInfoSetting> annotationInfoSettings = attributeMap.get(code);
        if (CollUtil.isEmpty(annotationInfoSettings)) {
            return null;
        }
        if (StrUtil.isEmpty(annotationPath)) {
            return null;
        }
        AnnotationInfoSetting annotationInfoSetting = annotationInfoSettings.get(annotationPath);

        return annotationInfoSetting;
    }

    public static Map<String, AnnotationInfo> builAnnotationInfo(PsiAnnotation[] annotations) {
        return Arrays.stream(annotations).map(annotation -> {
            AnnotationInfo annotationInfo = new AnnotationInfo();
            annotationInfo.setAnnotationName(Objects.requireNonNull(annotation.getNameReferenceElement()).getCanonicalText());
            Map<String, List<String>> stringListMap = buildAttributes(annotation.getParameterList().getAttributes());
            annotationInfo.setAnnotationAttributs(stringListMap);
            return annotationInfo;
        }).collect(Collectors.toMap(AnnotationInfo::getAnnotationName, a -> a));
    }

    public static Map<String, List<String>> buildAttributes(PsiNameValuePair[] attributes) {
        Map<String, List<String>> attributesMap = new HashMap<>();
        for (PsiNameValuePair attribute : attributes) {
            PsiAnnotationMemberValue value = attribute.getValue();
            String name = CharSequenceUtil.isEmpty(attribute.getName()) ? "null" : attribute.getName();
            if (value instanceof PsiAnnotation) {
                PsiAnnotation annotation = (PsiAnnotation) value;
                Map<String, List<String>> listMap = buildAttributes(annotation.getParameterList().getAttributes());
                attributesMap.putAll(listMap);
            } else {
                attributesMap.put(name, PsiAnnotationMemberUtil.oneExpression(value));
            }

        }
        return attributesMap;
    }

    public static List<String> getAllDescDort() {
        List<BambooDict> descSort = BambooToolComponent.getStoreService().getAllDictByCode(Arrays.asList(StringConstant.DESC_SORT));
        return descSort.stream().sorted(Comparator.comparing(BambooDict::getDescription)).map(BambooDict::getValue).collect(Collectors.toList());
    }


}
